import 'dart:collection';
import 'dart:convert';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:news/com.comm/contants/constant.dart';
import 'package:news/com.comm/utils/utils.dart';
import 'package:path_provider/path_provider.dart';
import 'package:syncfusion_flutter_xlsio/xlsio.dart';
import 'package:xml/xml.dart';

import '../contants/writer_type.dart';
import '../model/db_utils.dart';

class StringsUtils {
  /**
   * 插入新的多语言  写入或者替换
   */
  static Future<void> startInsertLanguage(String translateKey, Map transMap,
      String resPath, WriterType writerType) async {
    var listConfig = await DbUtils().loadTranslateConfig();
    var list_error = HashMap<String, String>();
    listConfig.forEach((element) {
      list_error[element[Constant.shortName]] = element[Constant.valuesName];
    });
    Directory directory = Directory(resPath);
    bool exists = await directory.exists();
    if (!exists) {
      print("$resPath 不存在或无法读写");
      return Future.value();
    }
    print("translateKey：$translateKey");

    transMap.forEach((key, value) {
      // if (translateListTag.containsKey(key)) {
      print("翻译语言：$key|$value");
      var valueName = list_error[key]; // values 多语言名称
      var resAllPath =
          "$resPath/values-$valueName/strings.xml"; // 当前要插入的多语言的全路径
      print("resAllPath:$resAllPath");
      print("valueName:$valueName");
      var keyTag = "</resources>";
      var valueContent =
          "    <string name=\"$translateKey\">$value</string>{n}</resources>";
      if (key == "en") {
        // 英语情况下多一步插入到默认语言栏
        var resEnPath = "$resPath/values/strings.xml"; // 当前要插入的多语言的全路径
        if (writerType == WriterType.insert) {
          writerTranslateInFile(resEnPath, keyTag, valueContent);
        } else {
          replaceTranslateInFile(resEnPath, translateKey, value.toString());
        }
      }
      if (writerType == WriterType.insert) {
        writerTranslateInFile(resAllPath, keyTag, valueContent);
      } else {
        replaceTranslateInFile(resAllPath, translateKey, value.toString());
      }
      // } else {
      //   print("插入语言：$key|不存在");
      // }
    });
    return Future.value();
  }

  /**
   * 根据对应的多语言翻译key 查询到所有的多语言
   */
  static Future<dynamic> getTranslateKeyLanguages(
      String translateKey, String resPath) async {
    Directory directory = Directory(resPath);
    bool exists = await directory.exists();
    if (!exists) {
      print("$resPath 不存在或无法读写");
      return Future.value("");
    }
    print("translateKey：$translateKey");
    var data = {};
    List translateListTag = await DbUtils().loadTranslateConfig();
    translateListTag.forEach((item) {
      var valueName = item[Constant.valuesName]; // values 多语言名称
      var resAllPath =
          "$resPath/values-$valueName/strings.xml"; // 当前要插入的多语言的全路径
      print("resAllPath:$resAllPath");
      print("valueName:$valueName");
      var file = File(resAllPath);
      if (!file.existsSync()) {
        print("文件不存在或无法读写");
        return;
      }
      var content = file.readAsStringSync();
      // 使用正则表达式查找name="clean_care"的<string>标签内的内容
      RegExp regExp = RegExp('<string name="${translateKey}">([^<]+)</string>');
      RegExpMatch? match = regExp.firstMatch(content);

      if (match != null) {
        // 提取并打印匹配到的内容
        String content = match.group(1)!;
        print(content); // 输出: Cleaning/Care
        data[item[Constant.shortName]] = content;
        print("translateKey:${content}");
      } else {
        print("未找到匹配项");
      }
    });
    return Future.value(data);
  }

  /**
   * 写入
   */
  static void writerTranslateInFile(
      String filePath, String oldString, String newString) {
    var file = File(filePath);
    if (!file.existsSync()) {
      print("文件不存在或无法读写");
      return;
    }
    if (newString.contains("@")) {
      newString = newString.replaceAll("@", "\\n");
    }
    if (newString.contains("{0}")) {
      newString = newString.replaceAll("{0}", "\\n");
    }
    if (newString.contains("\n")) {
      newString = newString.replaceAll("\n", "\\n");
    }
    debugPrint("newString:${newString}");
    var content = file.readAsStringSync();
    var replacedContent = content.replaceAll(oldString, newString);
    if (replacedContent.contains("{n}")) {
      replacedContent = replacedContent.replaceAll("{n}", "\n");
    }
    file.writeAsStringSync(replacedContent, flush: true);
    print("$newString 字符串替换成功");
  }

  /**
   * 替换
   */
  static void replaceTranslateInFile(
      String filePath, String keyTag, String newString) {
    var file = File(filePath);
    if (!file.existsSync()) {
      print("文件不存在或无法读写");
      return;
    }
    if (newString.contains("@")) {
      newString = newString.replaceAll("@", "\\n");
    }
    if (newString.contains("{0}")) {
      newString = newString.replaceAll("{0}", "\\n");
    }
    if (newString.contains("\n")) {
      newString = newString.replaceAll("\n", "\\n");
    }
    var content = file.readAsStringSync();
    var replacedContent = content.replaceAllMapped(
        RegExp('<string name="$keyTag">.*?</string>'),
        (match) => '<string name="$keyTag">$newString</string>');
    file.writeAsStringSync(replacedContent, flush: true);
    print("$newString 字符串替换成功");
  }

  /**
   * 根据英文翻译获取res key
   */
  static String getTranslateKey(String languageEn) {
    return languageEn
        .trim()
        .replaceAll(" ", "_")
        .replaceAll("-", "_")
        .replaceAll(",", "_")
        .replaceAll("\'", "_")
        .replaceAll("，", "_")
        .replaceAll(".", "")
        .replaceAll("。", "")
        .replaceAll("*", "")
        .replaceAll("@", "")
        .replaceAll("{0}", "")
        .replaceAll("\n", "_")
        .replaceAll("\\n", "_")
        .toLowerCase();
  }

  /**
   * 检测多语言是否存在
   */
  static bool isExistTranslateKey(String filePath, String translateKey) {
    // 构建完整的文件路径
    var file = File('$filePath/values/strings.xml');
    // 检查文件是否存在以及是否可读写
    if (!file.existsSync() || !file.readAsStringSync().isNotEmpty) {
      print("文件不存在或无法读写");
      return false;
    }
    // 读取文件内容
    var content = file.readAsStringSync();
    // 检查内容中是否包含特定的翻译键
    return content.contains('name="$translateKey"');
  }

  /**
   * 根据key 移除当前存在的翻译
   */
  static Future<void> removeTranslateByKey(
      String resPath, String keyTag) async {
    Directory directory = Directory(resPath);
    bool exists = await directory.exists();
    if (!exists) {
      print("$resPath 不存在或无法读写");
      return Future.value();
    }
    List translateListTag = await DbUtils().loadTranslateConfig();
    translateListTag.forEach((item) {
      var value = item[Constant.valuesName];
      var resAllPath = "$resPath/values-$value/strings.xml";
      if (value == "en") {
        resAllPath = "$resPath/values/strings.xml";
        _removeTranslateByKeySingle(resAllPath, keyTag);
      }
      resAllPath = "$resPath/values-$value/strings.xml";
      print("resAllPath: $resAllPath");
      print("valueName: $value");
      _removeTranslateByKeySingle(resAllPath, keyTag);
    });
    return Future.value();
  }

  /**
   * 移除多语言
   */
  static void _removeTranslateByKeySingle(String filePath, String keyTag) {
    var file = File(filePath);
    if (!file.existsSync()) {
      print("文件不存在或无法读写");
      return;
    }
    var content = file.readAsStringSync();
    var pattern = RegExp('<string name="$keyTag">.*?</string>', dotAll: true);
    var replacedContent = content.replaceAll(pattern, "");
    final lines = replacedContent.split('\n');
    final nonEmptyLines =
        lines.where((line) => line.trim().isNotEmpty).toList();
    // 将处理后的内容合并成字符串
    String processedContent = nonEmptyLines.join('\n');
    // 替换所有匹配的空白行为一个换行符
    file.writeAsStringSync(processedContent, flush: true);
    print("$keyTag：移除成功！");
  }

  /**
   * 多语言导出成excel
   */
  static void exportLanguage(
      String projectName, String resPath, String jsonPath) async {
    Directory directory = Directory(resPath);
    bool existsRes = await directory.exists();
    if (!existsRes) {
      showToast("多语言文件路径不存在");
      return;
    }

    var desktopPathLocal = await _getDesktopPath(); //获取桌面路径
    if (desktopPathLocal.isEmpty) {
      showToast("桌面路径不能为空！");
      return;
    }
    String formattedDateTime = _getTimeString(); //时间毫秒值

    Map listLanguage = await _getLanguageList(resPath); // 解析多语言
    if (listLanguage.isEmpty) {
      showToast("多语言数据不能为空！");
      return;
    }
    //开始保存界面多语言
    await _savePageLanguageExcel("界面多语言", listLanguage, desktopPathLocal,
        projectName, formattedDateTime);

    var file = File(jsonPath);
    if (!file.existsSync()) {
      showToast("故障码文件路径不存在");
      return;
    }
    List jsonListErrorLanguage =
        await _getJsonErrorLanguageList(jsonPath); // 解析故障码多语言
    if (listLanguage.isEmpty) {
      showToast("多语言数据不能为空！");
      return;
    }
    _saveJsonErrorLanguageExcel("故障码多语言", jsonListErrorLanguage,
        desktopPathLocal, projectName, formattedDateTime);

    showToast("多语言导出成功！");
  }

  /**
   * 保存界面多语言
   */
  static Future<void> _savePageLanguageExcel(
      String sheetName,
      Map<dynamic, dynamic> listLanguage,
      String desktopPathLocal,
      String projectName,
      String formattedDateTime) async {
    // 创建一个工作簿
    final Workbook workbook = Workbook();
    // 添加一个工作表
    final Worksheet sheet = workbook.worksheets[0];
    sheet.name = sheetName;
    Map<dynamic, dynamic> oneLanguageList = listLanguage.values.first;
    sheet.getRangeByIndex(1, 1).setText("code-key");
    // code-key 列表
    List oneLanguageListKeys = oneLanguageList.keys.toList();
    // 先加code-key
    for (int i = 0; i < oneLanguageList.length; i++) {
      int j = i + 2;
      sheet.getRangeByIndex(j, 1).setText(oneLanguageListKeys[i]);
    }
    // 再加标题
    List title_list = listLanguage.keys.toList();
    for (int i = 0; i < listLanguage.length; i++) {
      sheet.getRangeByIndex(1, i + 2).setText(title_list[i]);
    }

    // 然后加内容
    for (int i = 0; i < title_list.length; i++) {
      var currentLanguageKey = title_list[i];
      Map<dynamic, dynamic> currentLanguageList =
          listLanguage[currentLanguageKey];
      for (int j = 0; j < oneLanguageListKeys.length; j++) {
        var stringKey = oneLanguageListKeys[j];
        var stringValue = currentLanguageList[stringKey];
        sheet.getRangeByIndex(j + 2, i + 2).setText(stringValue);
      }
    }
    final String languageExportFilePath =
        '${desktopPathLocal}\\${projectName + "_界面多语言_" + formattedDateTime}.xlsx';
    // 保存工作簿
    final List<int> bytes = workbook.saveAsStream();
    await File(languageExportFilePath).writeAsBytes(bytes, flush: true);
    // 打印保存路径
    print('文件已保存到 $languageExportFilePath');
    // 关闭工作簿
    workbook.dispose();
  }

  /**
   * 保存故障码多语言
   */
  static Future<void> _saveJsonErrorLanguageExcel(
      String sheetName,
      List listLanguage,
      String desktopPathLocal,
      String projectName,
      String formattedDateTime) async {
    // 创建一个工作簿
    final Workbook workbook = Workbook();
    // 添加一个工作表
    final Worksheet sheet = workbook.worksheets[0];
    sheet.name = sheetName;
    //先加标题
    List title_list = [];
    if (listLanguage.isEmpty) {
      return Future.value();
    }
    var listConfig = await DbUtils().loadTranslateConfig();
    var list_error = HashMap<String, String>();
    listConfig.forEach((element) {
      list_error[element[Constant.shortName]] = element[Constant.errorName];
    });
    var values = listLanguage[0];
    values.forEach((key, value) {
      var realKey = "";
      for (var entry in list_error.entries) {
        if (entry.value == key) {
          realKey = entry.key;
          break;
        }
      }
      if (realKey.isNotEmpty) {
        title_list.add(realKey);
      }
    });
    title_list.insert(0, "code");
    for (int i = 0; i < title_list.length; i++) {
      sheet.getRangeByIndex(1, i + 1).setText(title_list[i]);
    }

    // 然后加内容
    for (int i = 0; i < title_list.length; i++) {
      var currentLanguageKey;
      if (i == 0) {
        currentLanguageKey = "code";
      } else {
        currentLanguageKey = list_error[title_list[i]];
      }
      for (int j = 0; j < listLanguage.length; j++) {
        var stringValue = listLanguage[j][currentLanguageKey];
        sheet.getRangeByIndex(j + 2, i + 1).setText(stringValue);
      }
    }
    final String languageExportFilePath =
        '${desktopPathLocal}\\${projectName + "_故障码多语言_" + formattedDateTime}.xlsx';
    // 保存工作簿
    final List<int> bytes = workbook.saveAsStream();
    await File(languageExportFilePath).writeAsBytes(bytes, flush: true);
    // 打印保存路径
    print('文件已保存到 $languageExportFilePath');
    // 关闭工作簿
    workbook.dispose();
  }

  /**
   * 获取时间毫秒值
   */
  static String _getTimeString() {
    // 定义一个格式化的字符串
    final DateFormat formatter = DateFormat('yyyy-MM-dd_HH_mm_ss');
    // 获取当前时间
    final now = DateTime.now();
    // 格式化时间
    final formattedDateTime = formatter.format(now);
    return formattedDateTime;
  }

  /**
   * 解析 安卓 res 目录下的多语言
   */
  static Future<Map<dynamic, dynamic>> _getLanguageList(
    String resPath,
  ) async {
    Map<dynamic, dynamic> listLanguage = {};
    var listConfig = await DbUtils().loadTranslateConfig();
    debugPrint("listConfig:${listConfig}");
    var list_error = [];
    listConfig.forEach((element) {
      dynamic item = {};
      item["key"] = element[Constant.shortName];
      item["value"] = element[Constant.valuesName];
      list_error.add(item);
    });
    debugPrint("list_error:${list_error}");
    list_error.forEach((item) {
      var key = item["key"]; // 多语言短名称
      var valueName = item["value"]; // values 多语言名称
      var resAllPath =
          "$resPath/values-$valueName/strings.xml"; // 当前要插入的多语言的全路径
      print("resAllPath:$resAllPath");
      print("valueName:$valueName");
      var file = File(resAllPath);
      if (!file.existsSync()) {
        print("文件不存在或无法读写");
        return;
      }
      var bookshelfXml = file.readAsStringSync();
      final document = XmlDocument.parse(bookshelfXml); //解析成xml对象
      var languageData = {}; //当前语种对象
      document.findAllElements('string').forEach((it) {
        var keyItem = it.attributes.first.value;
        var valueItem = it.innerText;
        languageData[keyItem] = valueItem;
      });
      listLanguage[key] = languageData;
    });
    return Future.value(listLanguage);
  }

  /**
   * 解析故障码多语言
   */
  static Future<List> _getJsonErrorLanguageList(
    String jsonPath,
  ) async {
    List listLanguage = [];
    var file = File(jsonPath);
    var jsonContent = file.readAsStringSync();
    listLanguage = jsonDecode(jsonContent);
    var listConfig = await DbUtils().loadTranslateConfig();
    List newListLanguage = [];
    listLanguage.forEach((item){
      dynamic newItem = {};
      newItem["code"] = item["code"];
      listConfig.forEach((element) {
        newItem[element[Constant.errorName]] = item[element[Constant.errorName]];
      });
      newListLanguage.add(newItem);
    });
    debugPrint("newListLanguage:${newListLanguage}");
    return newListLanguage;
  }

  /**
   * 获取当前桌面路径
   */
  static Future<String> _getDesktopPath() async {
    String desktopPathLocal = "";
    if (Platform.isWindows) {
      // 在 Windows 上获取桌面路径
      final directory = await getApplicationDocumentsDirectory();
      final desktopPath = Directory('${directory.parent.path}\\Desktop');
      desktopPathLocal = desktopPath.path;
    } else if (Platform.isMacOS) {
      // 在 macOS 上获取桌面路径
      final homeDir = await getApplicationDocumentsDirectory();
      final desktopPath = Directory('${homeDir.parent.path}/Desktop');
      desktopPathLocal = desktopPath.path;
    }
    return desktopPathLocal;
  }
}
